//
//  RTLChainRequest.m
//  RTLNetWorking
//
//  Created by 林波 on 16/7/11.
//  Copyright © 2016年 linbo1. All rights reserved.
//

#import "RTLChainRequest.h"

@interface RTLChainRequest () <RTLRequestAccessory,RTLBaseRequestDelegate>

// 存请求的多个接口
@property (nonatomic, strong, readwrite) NSMutableArray *requests;

// 请求回调
@property (strong, nonatomic) NSMutableArray *requestCallbackArray;

// 请求是否在运行
@property (nonatomic, assign, getter=isRunning) BOOL running;

// 请求是否可以取消
@property (nonatomic, assign, getter=isCanceling) BOOL canceling;

// 执行第几个请求
@property (assign, nonatomic) NSUInteger nextRequestIndex;

// 空的回调在最后一个的时候使用
@property (strong, nonatomic) RTLChainCallback emptyCallback;


@end

@implementation RTLChainRequest

/**
 *  初始化
 *
 *  @return <#return value description#>
 */
- (id)init{
    self = [super init];
    if (self) {
        self.requests = [NSMutableArray new];
        self.requestCallbackArray = [NSMutableArray new];
        _emptyCallback = ^(RTLChainRequest *chainRequest, RTLBaseRequest *baseRequest) {
            // do nothing
        };
    }
    return self;
}


/**
 *  链式请求
 *
 *  @param request  请求接口
 *  @param callback 成功后回调
 */
- (void)addRequest:(RTLBaseRequest *)request callback:(RTLChainCallback)callback {
    [_requests addObject:request];
    if (callback != nil) {
        [_requestCallbackArray addObject:callback];
    } else {
        [_requestCallbackArray addObject:_emptyCallback];
        [request start];
    }
}


/**
 *  开始下一个任务
 *
 *  @return YES:开始  NO:不开始
 */
- (BOOL)startNextRequest {
    if (_nextRequestIndex < [_requests count]) {
        RTLBaseRequest *request = _requests[_nextRequestIndex];
        _nextRequestIndex++;
        request.delegate = self;
        [request start];
        return YES;
    } else {
        return NO;
    }
}

#pragma mark - Network Request Delegate

/**
 *  请求完成
 *
 *  @param request 完成的请求
 */
- (void)requestFinished:(RTLBaseRequest *)request {
    NSUInteger currentRequestIndex = _nextRequestIndex - 1;
    RTLChainCallback callback = self.requestCallbackArray[currentRequestIndex];
    callback(self, request);
    if (![self startNextRequest]) {
        [self toggleAccessoriesRequestWillStop];
        if ([_delegate respondsToSelector:@selector(chainRequestFinished:)]) {
            [_delegate chainRequestFinished:self];
            [[RTLChainRequestManager sharedManager] removeChainRequest:self];
        }
        [self toggleAccessoriesRequestDidStop];
    }
}

/**
 *  请求失败
 *
 *  @param request 失败的请求
 */
- (void)requestFailed:(RTLBaseRequest *)request {
    [self toggleAccessoriesRequestWillStop];
    if ([_delegate respondsToSelector:@selector(chainRequestFailed:failedBaseRequest:)]) {
        [_delegate chainRequestFailed:self failedBaseRequest:request];
        [[RTLChainRequestManager sharedManager] removeChainRequest:self];
    }
    [self toggleAccessoriesRequestDidStop];
}

/**
 *  清除所有的请求
 */
- (void)clearRequest {
    NSUInteger currentRequestIndex = _nextRequestIndex - 1;
    if (currentRequestIndex < [self.requests count]) {
        RTLBaseRequest *request = self.requests[currentRequestIndex];
        [request cancel];
    }
    [self.requests removeAllObjects];
    [_requestCallbackArray removeAllObjects];
}



/**
 *  开始请求
 */
- (void)start
{
    if (_nextRequestIndex > 0) {
        NSLog(@"Error! Chain request has already started.");
        return;
    }
    if ([_requests count] > 0) {
        [self toggleAccessoriesRequestWillStart];
        [self startNextRequest];
        [[RTLChainRequestManager sharedManager] addChainRequest:self];
    } else {
        NSLog(@"Error! Chain request array is empty.");
    }

}


/**
 *  取消请求
 */
- (void)cancel {
    if (self.isCanceling) return;
    self.canceling = YES;
    [self cancelAllSubRequest];
}



/**
 *  开始
 *
 *  @param request 请求接口
 */

- (void)requestDidStart:(id)request {
    if (self.canceling && [request isKindOfClass:[RTLBaseRequest class]]) {
        [self cancelAllSubRequest];
    }
}

#pragma mark - Private

- (void)cancelAllSubRequest {
    for (RTLBaseRequest *request in self.requests) {
        if (request.canCancel) [request cancel];
    }
}

/**
 *  任务将要开始
 */
- (void)toggleAccessoriesRequestWillStart {
    for (id<RTLRequestAccessory> obj in self.requestCallbackArray) {
        if ([obj respondsToSelector:@selector(requestWillStart:)]) {
            [obj requestWillStart:self];
        }
    }
}

/**
 *  任务开始
 */
- (void)toggleAccessoriesRequestDidStart {
    for (id<RTLRequestAccessory> obj in self.requestCallbackArray) {
        if ([obj respondsToSelector:@selector(requestDidStart:)]) {
            [obj requestDidStart:self];
        }
    }
}


/**
 *  任务将要停止
 */
- (void)toggleAccessoriesRequestWillStop {
    for (id<RTLRequestAccessory> obj in self.requestCallbackArray) {
        if ([obj respondsToSelector:@selector(requestWillStop:)]) {
            [obj requestWillStop:self];
        }
    }
}

/**
 *  任务停止
 */
- (void)toggleAccessoriesRequestDidStop {
    for (id<RTLRequestAccessory> obj in self.requestCallbackArray) {
        if ([obj respondsToSelector:@selector(requestDidStop:)]) {
            [obj requestDidStop:self];
        }
    }
}

@end



@interface RTLChainRequestManager ()

@property (nonatomic, strong) NSMutableArray *chainRequests;

@end

@implementation RTLChainRequestManager

/**
 *  单例
 *
 *  @return <#return value description#>
 */
+ (instancetype)sharedManager {
    static RTLChainRequestManager *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [RTLChainRequestManager new];
        instance.chainRequests = [NSMutableArray array];
    });
    return instance;
}


/**
 *  加入链式请求
 *
 *  @param chainRequest 链式请求
 */
- (void)addChainRequest:(RTLChainRequest *)chainRequest {
    @synchronized (self) {
        [self.chainRequests addObject:chainRequest];
    }
}


/**
 *  移除链式请求
 *
 *  @param chainRequest 链式请求
 */
- (void)removeChainRequest:(RTLChainRequest *)chainRequest {
    @synchronized (self) {
        [self.chainRequests removeObject:chainRequest];
    }
}


@end
